package com.yf.system.modules.login.wechat;


import com.yf.ability.BaseConfig;
import com.yf.ability.login.wechat.config.WechatConfig;
import com.yf.ability.login.wechat.dto.request.WxLoginReqDTO;
import com.yf.ability.login.wechat.dto.request.WxUrlReqDTO;
import com.yf.ability.login.wechat.dto.response.WxInfoRespDTO;
import com.yf.ability.login.wechat.dto.response.WxLoginRespDTO;
import com.yf.ability.login.wechat.dto.response.WxUrlRespDTO;
import com.yf.ability.login.wechat.service.WxLoginService;
import com.yf.ability.shiro.dto.SysUserLoginDTO;
import com.yf.base.api.api.ApiRest;
import com.yf.base.api.api.controller.BaseController;
import com.yf.base.api.exception.ServiceException;
import com.yf.base.enums.PlatformType;
import com.yf.system.modules.user.enums.LoginType;
import com.yf.system.modules.user.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 微信登录后台处理类
 * @author bool
 */
@Log4j2
@Api(tags = {"微信登录"})
@RestController
public class WxLoginController extends BaseController {

    @Autowired
    private WxLoginService wxLoginService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private WechatConfig wechatConfig;

    @Autowired
    private BaseConfig baseConfig;


    /**
     * 登录地址
     */
    private final static String LOGIN_URL = "https://open.weixin.qq.com/connect/qrconnect?" +
            "appid={appId}&" +
            "redirect_uri={redirect}&" +
            "response_type=code&" +
            "scope=snsapi_login&" +
            "state={state}";


    /**
     * 获取微信登录跳转地址
     * @return
     */
    @PostMapping("/api/common/wx/get-url")
    @ApiOperation(value = "构建PC端微信登录地址", notes = "获取地址后直接跳转到登录地址，用户进行扫码登录")
    public ApiRest<WxUrlRespDTO> getUrl(@RequestBody WxUrlReqDTO reqDTO) {

        // state为登录跳转标识，可以跳转到h5页面
        String url = LOGIN_URL
                .replace("{appId}", wechatConfig.getSiteAppId())
                // 统一跳转地址
                .replace("{redirect}", baseConfig.getLoginRedirect())
                .replace("{state}", reqDTO.getState());

        WxUrlRespDTO respDTO = new WxUrlRespDTO();
        respDTO.setUrl(url);


        return success(respDTO);
    }


    /**
     * 小程序端微信登录
     * @return
     */
    @PostMapping("/api/common/wx/login")
    @ApiOperation(value = "小程序端微信登录", notes = "获得code后传入后台直接登录，返回登录信息")
    public ApiRest<SysUserLoginDTO> login(@RequestBody WxLoginReqDTO reqDTO) {
        WxLoginRespDTO resp = wxLoginService.login(
                reqDTO.getCode(),
                reqDTO.getNickName(),
                reqDTO.getAvatar());


        String uqId = resp.getUqId();

        if(StringUtils.isBlank(uqId)){
            throw new ServiceException("获取微信用户信息失败！");
        }

        // 登录并返回
        SysUserLoginDTO loginDTO = sysUserService.loginByThird(LoginType.WECHAT, uqId, reqDTO.getNickName(), reqDTO.getAvatar());
        return success(loginDTO);
    }



    /**
     * 网站的微信登录跳转
     * @param code
     * @return
     */
    @GetMapping("/api/common/wx/redirect")
    @ApiOperation(value = "微信PC端登录回调地址")
    public ApiRest<SysUserLoginDTO> webRedirect(HttpServletResponse response, @RequestParam("code") String code,
                                                @RequestParam("state") String state) throws IOException {


        // 获取会话
        WxInfoRespDTO resp = wxLoginService.webLogin(code);

        // 登录并返回
        SysUserLoginDTO loginDTO = sysUserService.loginByThird(LoginType.WECHAT, resp.getUqId(), resp.getNickName(), resp.getHeadimgurl());

        String redirect = "";

        // 跳转到H5版本
        if(PlatformType.H5.equals(state)){
            redirect = baseConfig.getLoginSyncH5();
        }

        // 跳转到PC版本
        if(PlatformType.PC.equals(state)){
            redirect = baseConfig.getLoginSyncPc();
        }

        // 替换地址
        redirect = redirect
                .replace("{token}", loginDTO.getToken())
                .replace("{roleType}", String.valueOf(loginDTO.getRoleType()));

        if(StringUtils.isBlank(redirect)){
            return super.failure("同步登录参数错误或跳转地址未配置！");
        }

        response.sendRedirect(redirect);
        return null;
    }
}
